import 'dart:convert';

import 'package:copilot_proxy/common.dart';
import 'package:copilot_proxy/context.dart';
import 'package:copilot_proxy/middleware/middleware.dart';
import 'package:crypto/crypto.dart';

Future<void> copilotTokenCheckAuth(
  String? token,
  Context context,
  Next next,
) async {
  if (!isCopilotTokenValid(token)) return;
  context.auth = true;
  await next();
}

bool isCopilotTokenValid(String? token) {
  if (token == null) return false;

  final parts = token.split(';');
  String? trackingId;
  int? expiresAt;
  String? updateHeaderFlag;
  String? clientId;
  String? sha256RandomStr;

  for (final part in parts) {
    final kv = part.split('=');
    if (kv.length != 2) continue;
    final key = kv[0];
    final value = kv[1];
    switch (key) {
      case 'tid':
        trackingId = value;
        break;
      case 'exp':
        expiresAt = int.tryParse(value);
        break;
      case 'uhf':
        updateHeaderFlag = value;
        break;
      case 'cid':
        clientId = value;
        break;
      case '8kp':
        sha256RandomStr = value.substring(2);
        break;
    }
  }

  if (trackingId == null || expiresAt == null || sha256RandomStr == null || updateHeaderFlag == null) {
    return false;
  }

  final now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
  if (now > expiresAt) {
    return false;
  }

  final sha256RandomDigest = sha256.convert(
    utf8.encode(
      '$expiresAt'
      '$trackingId'
      '${config.tokenSalt}'
      '$updateHeaderFlag'
      '$clientId',
    ),
  );
  return sha256RandomStr == sha256RandomDigest.toString();
}
